// XMLConfigFile.cpp
// 
// Copyright (c) Jason Sandys, 2009
//
// License: This code is released according to the 
// Microsoft Public License (Ms-PL) as documented at 
// http://osdappchooser.codeplex.com/license
//
//////////////////////////////////////////////////////////////////////

#include "StdAfx.h"
#include "XMLConfigFile.h"

//************************************************************
/**<summary>The default constructor, opens a file if one is 
passed in</summary>

<param name='szFilepath'>(in)The full path of a file to open at
construction time</param>
*/
 //************************************************************
CjXMLConfigFile::CjXMLConfigFile (LPCTSTR szFilepath) :
 m_docConfig(CLSID_DOMDocument60)
{
	if (szFilepath)
		LoadFile (szFilepath);
}
	
CjXMLConfigFile::~CjXMLConfigFile(void)
{
}

//************************************************************
/**<summary>Load the specified configuration file</summary>

<param name='szFilepath'>(in)The full path of the XML 
configuration file to open</param>
*/
//************************************************************
void CjXMLConfigFile::LoadFile (LPCTSTR szFilepath)
{
	VARIANT_BOOL ok;
	
	//Check to ensure that a valid string was actually passed in
	if ( szFilepath == 0 || _tcsnlen (szFilepath, MAX_STRING_LENGTH) == 0 )
	{
		throw Error (false, (DWORD)IDS_ERRORCONFIGFILENOTSPECIFIED);
	}

	//Set the DOM object to load the whole configuration file
	m_docConfig->async = VARIANT_FALSE;
	
	//Load the confiuration file into the DOM object
	ok = m_docConfig->load (szFilepath);

	long err = m_docConfig->parseError->errorCode;

	//Check to make sure the configuration file is valid XML
	if (err != S_OK || ok != VARIANT_TRUE)
		throw Error (m_docConfig->parseError, szFilepath);

	try
	{
		//Set the query language for the DOM object to XPath
		m_docConfig->setProperty (_T("SelectionLanguage"), _T("XPath"));
	}
	catch (_com_error ce)
	{
		throw Error (false, (DWORD)IDS_ERRORLANGSET);
	}
}

//************************************************************
/**<summary>Load a specified node/element</summary>

<param name='eLoad'>(out)Reference to the element object 
loaded</param>
<param name='strElementName'>(in)The name of the element to
load</param>
<param name='dwNodeLoadError'>(in)The error number to throw
if the node cannot be loaded</param>
*/
//************************************************************

void CjXMLConfigFile::LoadNode(XmlElement& eLoad, CString strElementName, DWORD dwNodeLoadError)
{
	//If the node is already populated, return
	if (eLoad != 0)
		return;
	
	//Make sure the document is properly loaded and a document element exists
	if (m_docConfig->documentElement == 0)
		throw Error (false, (DWORD)IDS_ERRORROOTNODENOTLOADED);

	try
	{
		//Get the first node from the document that matches the type passes in
		eLoad = m_docConfig->documentElement->selectSingleNode (strElementName.AllocSysString ());

		//Make sure a node got selected
		if (eLoad == 0)
			throw Error (false, dwNodeLoadError);
	}
	catch (_com_error ce)
	{
		throw Error (false, dwNodeLoadError);
	}
}